package com.htfyun.test.comparefile;

import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.ref.WeakReference;

public class MainActivity extends AppCompatActivity {


    private final static String TAG = "HtfyunTest";

    private final static String PATH_FILE_1 = "/sdcard/usb_test/1.bin";
    private final static String PATH_FILE_2 = "/sdcard/usb_test/2.bin";


    public final static int ONE_M = 1024 * 1024;//1M = 1024 * 1024 bytes

    private TextView txtLog;

    private View btnStart;

    private Context mContext;

    private MyHandler handler;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mContext = this;

        txtLog = (TextView) findViewById(R.id.txtLog);

        TextView txtTips = (TextView) findViewById(R.id.txtTips);

        txtTips.setText("对比文件: " + PATH_FILE_1 + " 和 " + PATH_FILE_2);

        btnStart = findViewById(R.id.btnStart);
        btnStart.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                v.setEnabled(false);
                txtLog.setText("");
                new Thread(testRunnable).start();

                updateLog("开始测试");

            }
        });

        handler = new MyHandler(this);

        if (isGotPermission()) {
            startCopyFile();
        } else {
            initPermission();
        }

    }

    private void startCopyFile() {
//        new Thread(copyFileRunnable).start();

    }

    private void endTest() {
        handler.sendEmptyMessage(MyHandler.MSG_END);
    }

    private void updateLog(String log) {
        handler.obtainMessage(MyHandler.MSG_UPDATE_LOG, log).sendToTarget();
    }

    private void doUpdateLog(String log) {
        String txt = txtLog.getText().toString();
        if (txt.length() > 1024 * 6) {
            txtLog.setText(log);
        } else {
            txtLog.setText(txt + "\n" + log);
        }
    }

    private Runnable copyFileRunnable = new Runnable() {

        private final String DST_PATH = "/mnt/test.bin";

        private final static String SRC_PATH = "/system/app/webview/webview.apk";

        @Override
        public void run() {

            Log.e(TAG, "copy start");
            copyFile(SRC_PATH, DST_PATH);


        }

        private void copyFile(String srcFilePath, String desFilePath) {

            File srcFile = new File(srcFilePath);
            if (!srcFile.exists()) {
                updateLog(srcFilePath + " is not exist");
                return;
            }

            File desFile = new File(desFilePath);
            if (desFile.exists()) {
                updateLog(desFilePath + " is exist, return");
                return;
            }


            try {
                desFile.createNewFile();
            } catch (IOException e) {
                updateLog(desFilePath + " failed to create, err = " + e.getMessage());
                e.printStackTrace();
                return;
            }


            OutputStream writer = null;
            InputStream reader = null;

            try {

                byte[] buffer = new byte[ONE_M];

                int length = 0;

                reader = new FileInputStream(srcFile);
                writer = new FileOutputStream(desFile, true);


                while ((length = reader.read(buffer)) != -1) {

                    writer.write(buffer, 0, length);

                    writer.flush();

                }

            } catch (Exception e) {
                Log.e(TAG, "Exception = " + e.getMessage());
                e.printStackTrace();

            } finally {

                if (writer != null) {
                    try {
                        writer.close();
                        writer = null;
                    } catch (Exception e1) {
                        Log.e(TAG, "Exception = " + e1.getMessage());
                        e1.printStackTrace();
                    }
                }

                if (reader != null) {
                    try {
                        reader.close();
                        reader = null;
                    } catch (Exception e1) {
                        Log.e(TAG, "Exception = " + e1.getMessage());
                        e1.printStackTrace();
                    }
                }
            }
        }
    };

    private Runnable testRunnable = new Runnable() {
        @Override
        public void run() {
            testFile(PATH_FILE_1, PATH_FILE_2);

            endTest();

        }

        private void testFile(String fileOnePath, String fileTwoPath) {

            File fileOne = new File(fileOnePath);
            if (!fileOne.exists()) {
                updateLog(fileOnePath + "is not exist");
                return;
            }

            File fileTwo = new File(fileTwoPath);

            if (!fileTwo.exists()) {
                updateLog(fileTwoPath + "is not exist");
                return;
            }


            InputStream readOne = null;
            InputStream readTwo = null;
            try {

                readOne = new FileInputStream(fileOne);
                readTwo = new FileInputStream(fileTwo);

                byte[] bufOne = new byte[ONE_M];
                byte[] bufTwo = new byte[ONE_M];

                int lengthOne = 0;
                int lengthTwo = 0;
                int cycleCount = 0;

                while ((lengthOne = readOne.read(bufOne)) != -1 && (lengthTwo = readTwo.read(bufTwo)) != -1) {

                    if (lengthOne == lengthTwo) {
                        for (int i = 0; i < lengthOne; i++) {
                            if (bufOne[i] != bufTwo[i]) {
                                updateLog("compare -> " + "offset = " + (cycleCount * bufOne.length + i)
                                        + ", bufOne = 0x" + Integer.toHexString((0xff & bufOne[i]))
                                        + ", bufTwo = 0x" + Integer.toHexString((0xff & bufTwo[i]))
                                );

                            }
                        }
                    }

                    cycleCount++;

                }


            } catch (Exception e) {
                Log.e(TAG, "Exception = " + e.getMessage());
                e.printStackTrace();

            } finally {

                if (readOne != null) {
                    try {
                        readOne.close();
                        readOne = null;
                    } catch (Exception e1) {
                        Log.e(TAG, "Exception = " + e1.getMessage());
                        e1.printStackTrace();
                    }

                }


                if (readTwo != null) {
                    try {
                        readTwo.close();
                        readTwo = null;
                    } catch (Exception e1) {
                        Log.e(TAG, "Exception = " + e1.getMessage());
                        e1.printStackTrace();
                    }

                }

            }
        }
    };

    private static class MyHandler extends Handler {


        public static final int MSG_UPDATE_LOG = 100;
        public static final int MSG_END = 101;
        private final WeakReference<MainActivity> activityWeakReference;

        private MyHandler(MainActivity activity) {
            super(Looper.getMainLooper());

            activityWeakReference = new WeakReference<MainActivity>(activity);
        }

        @Override
        public void handleMessage(Message msg) {
            //弱引用会在下一次gc时回收
            MainActivity activity = activityWeakReference.get();
            if (activity == null) {
                return;
            }

            switch (msg.what) {
                case MSG_UPDATE_LOG:
                    activity.doUpdateLog((String) msg.obj);
                    break;
                case MSG_END:
                    activity.btnStart.setEnabled(true);
                    activity.updateLog("测试结束");
                    break;
                default:
                    break;
            }

        }
    }


    private void initPermission() {
        //如果无权限就申请然后回调，如果有权限就执行录音监听
        if (!isGotPermission()) {
            //同时申请多个权限
            PermissionManager.getInstance(getApplicationContext()).execute(this,
                    android.Manifest.permission.WRITE_EXTERNAL_STORAGE);

        }

    }

    private boolean isGotPermission() {

        return ContextCompat.checkSelfPermission(mContext, android.Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;

    }

    //如果有权限的话返回
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        PermissionManager.getInstance(getApplicationContext()).
                onRequestPermissionsResult(requestCode, permissions, grantResults);


        Log.e(TAG, "11111");
        startCopyFile();
    }
}
